package com.yami.shop.nft.common.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.AsyncCoinDTO;
import com.yami.shop.bean.model.Blockchain;
import com.yami.shop.bean.model.BlockchainShop;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.common.bean.PageDTO;
import com.yami.shop.common.bean.PageVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.DataWebService;
import com.yami.shop.common.util.PageUtil;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.nft.common.dao.NftDawMapper;
import com.yami.shop.nft.common.dao.NftDenomMapper;
import com.yami.shop.nft.common.dto.NftDenomDto;
import com.yami.shop.nft.common.model.NftApply;
import com.yami.shop.nft.common.model.NftDaw;
import com.yami.shop.nft.common.model.NftDenom;
import com.yami.shop.nft.common.service.NftApplyService;
import com.yami.shop.nft.common.service.NftDenomService;
import com.yami.shop.service.BlockchainService;
import com.yami.shop.service.BlockchainShopService;
import com.yami.shop.service.ShopDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@Slf4j
public class NftDenomServiceImpl extends ServiceImpl<NftDenomMapper, NftDenom> implements NftDenomService {

    @Autowired
    private NftDenomMapper nftDenomMapper;

    @Autowired
    private ShopConfig shopConfig;

    @Autowired
    private BlockchainShopService blockchainShopService;

    @Autowired
    private DataWebService dataWebService;

    @Autowired
    private NftDawMapper nftDawMapper;

    @Autowired
    private NftApplyService nftApplyService;

    @Autowired
    private BlockchainService blockchainService;

    @Autowired
    private ShopDetailService shopDetailService;


    @Override
    public List<NftDenom> selectNftDenom(NftDenomDto nftDenomDto) {
        // 已经申请过的Denom
        LambdaQueryWrapper<NftDenom> nftDenomLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtils.isNotEmpty(nftDenomDto.getDenomId())) {
            nftDenomLambdaQueryWrapper.eq(NftDenom::getDenomId, nftDenomDto.getDenomId());
        }
        if (nftDenomDto.getSysType() == 1) {
            nftDenomLambdaQueryWrapper.eq(NftDenom::getShopId, nftDenomDto.getShopId());
            LambdaQueryWrapper<NftApply> lisQw = new LambdaQueryWrapper<NftApply>().eq(NftApply::getShopId, nftDenomDto.getShopId()).ne(NftApply::getApplyStatus, 1);
            List<NftApply> useList = nftApplyService.list(lisQw);
            List<String> denomIds = useList.stream().map(NftApply::getDenomId).collect(Collectors.toList());
            if(ObjectUtils.isNotEmpty(denomIds)){
                nftDenomLambdaQueryWrapper.notIn(NftDenom::getDenomId,denomIds);
            }
        }
        nftDenomLambdaQueryWrapper.eq(NftDenom::getIsbindStatus, 0);
        nftDenomLambdaQueryWrapper.orderByDesc(NftDenom::getCreateTime);
        return list(nftDenomLambdaQueryWrapper);
    }

    @Override
    public PageVO<NftDenom> pageNftDenom(PageDTO pageDTO, NftDenomDto nftDenomDto) {
        LambdaQueryWrapper<NftDenom> nftDenomLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtils.isNotEmpty(nftDenomDto.getDenomId())) {
            nftDenomLambdaQueryWrapper.eq(NftDenom::getDenomId, nftDenomDto.getDenomId());
        }
        if (ObjectUtils.isNotEmpty(nftDenomDto.getDenomName())) {
            nftDenomLambdaQueryWrapper.like(NftDenom::getDenomName, nftDenomDto.getDenomName());
        }
        if (nftDenomDto.getSysType() == 1) {
            nftDenomLambdaQueryWrapper.eq(NftDenom::getShopId, nftDenomDto.getShopId());
        }
        nftDenomLambdaQueryWrapper.orderByDesc(NftDenom::getCreateTime);
        PageVO<NftDenom> page = PageUtil.doPage(pageDTO, () -> nftDenomMapper.selectList(nftDenomLambdaQueryWrapper));
        if (ObjectUtils.isNotEmpty(page.getList())) {
            for (NftDenom nftDenom : page.getList()) {
                LambdaQueryWrapper<NftDaw> nftDawLambdaQueryWrapper = new LambdaQueryWrapper<NftDaw>().eq(NftDaw::getDenomId, nftDenom.getDenomId());
                long count = nftDawMapper.selectCount(nftDawLambdaQueryWrapper);
                nftDenom.setCount(count);
                LambdaQueryWrapper<Blockchain> blockchainShopLambdaQueryWrapper = new LambdaQueryWrapper<Blockchain>().eq(Blockchain::getCode, nftDenom.getBlockchainCode());
                Blockchain blockchain = blockchainService.getOne(blockchainShopLambdaQueryWrapper);
                nftDenom.setBlockchainName(blockchain.getName());
            }
        }
        return page;
    }

    @Override
    public NftDenom insertDenom(NftDenomDto nftDenomDto) {
//        LambdaQueryWrapper<BlockchainShop> eq = new LambdaQueryWrapper<BlockchainShop>().eq(BlockchainShop::getShopId, nftDenomDto.getShopId()).eq(BlockchainShop::getBlockchainCode, nftDenomDto.getBlockchainCode());
//        BlockchainShop blockchainShop = blockchainShopService.getOne(eq);
//        if (ObjectUtils.isEmpty(blockchainShop)) {
//            throw new YamiShopBindException("该店铺暂无铸币权限");
//        }
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(nftDenomDto.getShopId());
        Map<String, String> stringObjectMap3 = new HashMap<>();
        String url = shopConfig.getApiGatewayUrl() + "/nft/outapi/nftUser/getInfoForRomate";
//        String url ="192.168.1.127:9209/outapi/nftUser/getInfoForRomate";
//        JSONObject jsonObject = dataWebService.hutoolPostWebService(url, stringObjectMap3,shopDetail.getApiUser(),shopDetail.getApiPassword());
//        if (jsonObject.getInteger("code")== Constant.WARN) {
//            throw new YamiShopBindException(jsonObject.getString("msg"));
//        }else if(jsonObject.getInteger("code") != Constant.SUCCESS_CODE){
//            log.info("该店铺暂无申请铸币权限{}",jsonObject.getString("msg"));
//            throw new YamiShopBindException("该店铺暂无申请铸币权限");
//        }


        //创建品类
        String dtUrl = shopConfig.getApiGatewayUrl() + "/nft/outapi/api/nftmint/issueDenom?";
//        String dtUrl = "192.168.1.127:9209/outapi/api/nftmint/issueDenom?";
        Map<String, String> param = new HashMap<>();
//        LambdaQueryWrapper<BlockchainShop> dt = new LambdaQueryWrapper<BlockchainShop>().eq(BlockchainShop::getShopId, nftDenomDto.getShopId()).eq(BlockchainShop::getBlockchainCode, nftDenomDto.getBlockchainCode()).eq(BlockchainShop::getStatus, 1);
//        BlockchainShop one = blockchainShopService.getOne(dt);
//        if (ObjectUtils.isEmpty(one)) {
//            throw new YamiShopBindException("该店铺没有铸币资格");
//        }
//        // 获取链上地址
//        LambdaQueryWrapper<Blockchain> blockchainShopLambdaQueryWrapper = new LambdaQueryWrapper<Blockchain>().eq(Blockchain::getCode, nftDenomDto.getBlockchainCode());
//        Blockchain blockchain = blockchainService.getOne(blockchainShopLambdaQueryWrapper);

        String symbol = IdUtil.simpleUUID();
        String operationId = "dtc"+ IdUtil.simpleUUID();
        String str = null;
        if(nftDenomDto.getBlockchainCode().equals("hw")){
            str = IdUtil.objectId();
        }else{
            str = IdUtil.simpleUUID();
        }
        String denomId = "denom" + str;
        // 获取铸币账号密码
        param.put("denomName", nftDenomDto.getDenomName());
//        param.put("channel", one.getShopCode());
        param.put("denomId", denomId);
        param.put("chain",nftDenomDto.getBlockchainCode());
//        param.put("owner",blockchain.getAddress());
        param.put("symbol",symbol);
        param.put("operationId",operationId);
        param.put("dtcName",shopDetail.getApiUser());
        param.put("password",shopDetail.getApiPassword());
//        JSONObject jsonObjects = dataWebService.hutoolPostWebService(dtUrl, param,shopDetail.getApiUser(),shopDetail.getApiPassword());
//        if (jsonObjects.getInteger("code")== Constant.WARN) {
//            throw new YamiShopBindException(jsonObjects.getString("msg"));
//        }else if(jsonObjects.getInteger("code") != Constant.SUCCESS_CODE){
//            log.info("铸币异常{}",jsonObjects.getString("msg"));
//            throw new YamiShopBindException("铸币异常");
//        }
        NftDenom nftDenom = new NftDenom();
        if(nftDenomDto.getBlockchainCode().equals("avata") || nftDenomDto.getBlockchainCode().equals("szavata")){
            nftDenom.setDenomId(null);
            nftDenom.setSymbol(symbol);
            nftDenom.setOperationId(operationId);
            nftDenom.setOwner("");
        }else{
            nftDenom.setDenomId(denomId);
        }
        nftDenom.setCreateTime(new Date());
        nftDenom.setShopId(nftDenomDto.getShopId().intValue());
        nftDenom.setBlockchainCode(nftDenomDto.getBlockchainCode());
        nftDenom.setDenomName(nftDenomDto.getDenomName());
        nftDenom.setIsbindStatus(0);

        save(nftDenom);
        return nftDenom;
    }

    @Override
    public List<NftDenom> getDenomList(Long shopId, Integer status) {
        LambdaQueryWrapper<NftDenom> nftDenomLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nftDenomLambdaQueryWrapper.eq(NftDenom::getShopId, shopId);
        if (status != 0) {
            nftDenomLambdaQueryWrapper.eq(NftDenom::getIsbindStatus, 0);
        }
        nftDenomLambdaQueryWrapper.orderByDesc(NftDenom::getCreateTime);
        List<NftDenom> list = list(nftDenomLambdaQueryWrapper);
        if (ObjectUtils.isNotEmpty(list)) {
            for (NftDenom nftDenom : list) {
                LambdaQueryWrapper<NftDaw> nftDawLambdaQueryWrapper = new LambdaQueryWrapper<NftDaw>().eq(NftDaw::getDenomId, nftDenom.getDenomId()).eq(NftDaw::getChainUpStatus, 2).eq(NftDaw::getUseStatus,0);
                long count = nftDawMapper.selectCount(nftDawLambdaQueryWrapper);
                nftDenom.setCount(count);
            }
        }
        return list;
    }

    @Override
    public void updateDenomStatusByDenomId(String denomId) {
        LambdaUpdateWrapper<NftDenom> set = new LambdaUpdateWrapper<NftDenom>().eq(NftDenom::getDenomId, denomId);
        NftDenom nftDenom = new NftDenom();
        nftDenom.setIsbindStatus(1);
        nftDenomMapper.update(nftDenom, set);
    }

    @Override
    public NftDenom selectDenomIdByProdName(AsyncCoinDTO asyncCoinDTO) {
        LambdaQueryWrapper<NftDenom> nftDenomLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nftDenomLambdaQueryWrapper.eq(NftDenom::getDenomName,asyncCoinDTO.getProdName()).eq(NftDenom::getShopId,asyncCoinDTO.getShopId()).last("limit 1");
        NftDenom nftDenom = nftDenomMapper.selectOne(nftDenomLambdaQueryWrapper);
        return nftDenom;
    }

}
